namespace Yaaf.WP7.NativeAccess.Helper
{
    using System;
    using System.Collections.Generic;
    using System.Xml.Linq;

    public class ProvisonXmlBuilder
    {
        List<ProvisonXmlCharacteristic> characteristics = new List<ProvisonXmlCharacteristic>();
        public void AddCharacteristic(ProvisonXmlCharacteristic characteristic)
        {
            characteristics.Add(characteristic);
        }

        public XElement ToXml()
        {
            var xml = new XElement("wap-provisioningdoc");
            foreach (var provisonXmlCharacteristic in characteristics)
            {
                xml.Add(provisonXmlCharacteristic.ToXml());
            }

            return xml;
        }

        public override string ToString()
        {
            return ToXml().ToString();
        }
    }

    public class ProvisonXmlParm
    {
        public string Name { get; set; }
        public string Value { get; set; }
        public string Datatype { get; set; }

        public ProvisonXmlParm(bool noParm = false)
        {
            this.NoParm = noParm;
        }

        public bool NoParm { get; private set; }

        public string Translation { get; set; }

        public XElement ToXml()
        {
            var elem = new XElement(NoParm ? "noparm" : "parm");
            elem.Add(new XAttribute("name", Name));
            if (!string.IsNullOrEmpty(Value))
            {
                elem.Add(new XAttribute("value", Value));
            }
            if (!string.IsNullOrEmpty(Datatype))
            {
                elem.Add(new XAttribute("datatype", Datatype));
            }
            if (!string.IsNullOrEmpty(Translation))
            {
                elem.Add(new XAttribute("translation", Translation));
            }
            return elem;
        }
    }

    public class ProvisonXmlCharacteristic
    {
        private List<ProvisonXmlCharacteristic> characteristics = new List<ProvisonXmlCharacteristic>();

        private List<ProvisonXmlParm> parameter = new List<ProvisonXmlParm>();

        public ProvisonXmlCharacteristic(bool noCharacteristic = false)
        {
            this.NoCharacteristic = noCharacteristic;
        }

        public string Type { get; set; }

        public string Translation { get; set; }
        public bool NoCharacteristic { get; private set; }

        private bool param = false;
        private bool characteristicAdded = false;

        public void AddCharacteristic(ProvisonXmlCharacteristic characteristic)
        {
            if (param)
            {
                throw new InvalidOperationException("params are already added!");
            }

            if (NoCharacteristic)
            {
                throw new InvalidOperationException("can't add to nocharacteristic");
            }
            characteristicAdded = true;
            characteristics.Add(characteristic);
        }

        public void AddParam(ProvisonXmlParm parm)
        {
            if (characteristicAdded)
            {
                throw new InvalidOperationException("characteristics are already added!");
            } 
            if (NoCharacteristic)
            {
                throw new InvalidOperationException("can't add to nocharacteristic");
            }
            param = true;

            parameter.Add(parm);
        }

        public XElement ToXml()
        {
            string name;
            if (NoCharacteristic)
            {
                name = "nocharacteristic";
            }
            else
            {
                name = "characteristic";
            }
            var elem = new XElement(name);
            if (!string.IsNullOrEmpty(Type))
            {
                elem.Add(new XAttribute("type", Type));
            }
            if (!string.IsNullOrEmpty(Translation))
            {
                elem.Add(new XAttribute("translation", Translation));
            }

            if (NoCharacteristic)
            {
                return elem;
            }

            if (param && characteristicAdded)
            {
                throw new InvalidOperationException("param && characteristicAdded!");
            }

            if (param)
            {
                foreach (var provisonXmlParm in parameter)
                {
                    elem.Add(provisonXmlParm.ToXml());
                }
            }

            if (characteristicAdded)
            {
                foreach (var provisonXmlCharacteristic in characteristics)
                {
                    elem.Add(provisonXmlCharacteristic.ToXml());
                }
            }

            return elem;
        }
    }
}